home *** CD-ROM | disk | FTP | other *** search
/ Mac-Source 1994 July / Mac-Source_July_1994.iso / C and C++ / System / Sample 2.4 Think C distribution / ldf.c < prev    next >
Text File  |  1990-07-19  |  6KB  |  203 lines

  1. /*______________________________________________________________________
  2.  
  3.     ldf.c - List Definition Procedure for the Report Module.
  4.     
  5.     Copyright © 1988, 1989, 1990 Northwestern University.  Permission is 
  6.     granted to use this code in your own projects, provided you give 
  7.     credit to both John Norstad and Northwestern University in your 
  8.     about box or document.
  9.  
  10.     This LDEF is used by type 1 reports.  It ignores all but draw
  11.     messages.  The cell data specifies the index in the auxiliary array
  12.     of a handle to an STR# resource, and the offset of the line within
  13.     the resource.
  14. _____________________________________________________________________*/
  15.  
  16.  
  17. #include "doc.h"
  18.  
  19. #define nil 0
  20. #define normal 0        /* Think C doesn't know what normal is. */
  21.  
  22. pascal void main (short lMessage, Boolean lSelect, 
  23.     Rect *lRect, Cell *lCell, short lDataOffset,
  24.     short lDataLen, ListHandle lHandle)
  25.     
  26. {
  27.     auxInfo            **aux;            /* handle to auxiliary info */
  28.     Handle            theCells;        /* handle to cell data */
  29.     unsigned char    *p;                /* pointer to cell data */
  30.     Handle            theStrings;        /* handle to STR# resource */
  31.     unsigned short    offset;            /* offset of line in STR# resource */
  32.     unsigned char    *theLine;        /* pointer to the line */
  33.     unsigned char    *q;                /* pointer to cur pos in the line */
  34.     unsigned char    *qEnd;            /* pointer to end of line */
  35.     short                nchar;            /* number of chars to draw */
  36.     short                baseLine;        /* base line for text */
  37.     Boolean            escStyle;        /* true if style escape sequence */
  38.     Boolean            escJust;            /* true if just escape sequence */
  39.     Boolean            escPict;            /* true if pict escape sequence */
  40.     unsigned char    styleCode;        /* style */
  41.     unsigned char    justCode;        /* justification */
  42.     short                cellHeight;        /* cell height */
  43.     short                cellWidth;        /* cell width */
  44.     short                picID;            /* pict resource id */
  45.     short                picBand;            /* pict band number */
  46.     PicHandle        picHandle;        /* handle to pict */
  47.     short                picWidth;        /* pict width */
  48.     short                picHeight;        /* pict height */
  49.     Rect                picRect;            /* pict offscren rectangle */
  50.     Rect                picSrcRect;        /* CopyBits source rect */
  51.     Rect                picDstRect;        /* CopyBits dest rect */
  52.     GrafPort            picPort;            /* grafport for offscreen PICT drawing */
  53.     BitMap            picMap;            /* bitmap for offscreen PICT drawing */
  54.     
  55.     /* Get pointer to the line to be drawn. */
  56.     
  57.     if (lMessage != lDrawMsg) return;
  58.     aux = (auxInfo**)(**lHandle).userHandle;
  59.     theCells = (Handle)(**lHandle).cells;
  60.     p = (unsigned char *)*theCells + lDataOffset;
  61.     theStrings = (**aux).auxArray[*p++];
  62.     offset = (*p << 8) | *(p+1);
  63.     if (!*theStrings) LoadResource(theStrings);
  64.     HLock(theStrings);
  65.     theLine = (unsigned char *)*theStrings + offset;
  66.     
  67.     /* Get escape sequence info. */
  68.     
  69.     escStyle = escJust = escPict = false;
  70.     q = theLine+1;
  71.     qEnd = q + *theLine;
  72.     while (q < qEnd && *q < 31) {
  73.         switch (*q) {
  74.             case docStyle:
  75.                 escStyle = true;
  76.                 styleCode = *(q+2);
  77.                 break;
  78.             case docJust:
  79.                 escJust = true;
  80.                 justCode = *(q+2);
  81.                 break;
  82.             case docPict:
  83.                 escPict = true;
  84.                 picID = *(q+2)<<8 | *(q+3);
  85.                 picBand = *(q+4)<<8 | *(q+5);
  86.                 break;
  87.         };
  88.         q += *(q+1);
  89.     };
  90.                     
  91.     if (escPict) {
  92.     
  93.         /* Draw a picture. */
  94.         
  95.         cellWidth = lRect->right - lRect->left;
  96.         cellHeight = (**lHandle).cellSize.v;
  97.         
  98.         if ((**aux).cachedPictID != picID) {
  99.         
  100.             /* This picture is not cached - we must cache it in an offscreen
  101.                 bitmap. */
  102.             
  103.             /* Dispose of any previously cached bitmap. */
  104.             
  105.             if ((**aux).cachedPictID) DisposPtr((**aux).cachedBitMap.baseAddr);
  106.             
  107.             /* Compute picRect = the bounds rectangle for the cached
  108.                 picture. */
  109.             
  110.             picHandle = GetPicture(picID);
  111.             if (!picHandle) {
  112.                 HUnlock(theStrings);
  113.                 return;
  114.             };
  115.             if (!*picHandle) LoadResource((Handle)picHandle);
  116.             HLock((Handle)picHandle);
  117.             picWidth = (**picHandle).picFrame.right -
  118.                 (**picHandle).picFrame.left;
  119.             picHeight = (**picHandle).picFrame.bottom -
  120.                 (**picHandle).picFrame.top;
  121.             if (!escJust) justCode = docCenter;
  122.             switch (justCode) {
  123.                 case docLeft:
  124.                     picRect.left = lRect->left + 4;
  125.                     break;
  126.                 case docCenter:
  127.                     picRect.left = lRect->left + 
  128.                         ((cellWidth - picWidth)>>1);
  129.                     break;
  130.                 case docRight:
  131.                     picRect.left = lRect->right - 4 - picWidth;
  132.                     break;
  133.             };
  134.             picRect.right = picRect.left + picWidth;
  135.             picRect.top = 0;
  136.             picRect.bottom = picHeight;
  137.     
  138.             /* Allocate and initialize the offscreen  bitmap. */
  139.             
  140.             (**aux).cachedPictID = picID;
  141.             picMap.bounds = picRect;
  142.             picMap.rowBytes = (((picWidth+7)>>3) + 1) & 0xfffe;
  143.             picMap.baseAddr = NewPtr(picMap.rowBytes*picHeight);
  144.             (**aux).cachedBitMap = picMap;
  145.             
  146.             /* Draw the picture in the offscreen bitmap. */
  147.             
  148.             OpenPort(&picPort);
  149.             SetPortBits(&picMap);
  150.             picPort.portRect = picRect;
  151.             RectRgn(picPort.visRgn, &picRect);
  152.             ClipRect(&picRect);
  153.             EraseRect(&picRect);
  154.             DrawPicture(picHandle, &picRect);
  155.             HUnlock((Handle)picHandle);
  156.             ClosePort(&picPort);
  157.             SetPort((**lHandle).port);
  158.         };
  159.  
  160.         /* CopyBits the proper band from the offscreen cached bitmap to
  161.             the cell. */
  162.             
  163.         picMap = (**aux).cachedBitMap;
  164.         picSrcRect = picMap.bounds;
  165.         picSrcRect.top = picBand*cellHeight;
  166.         picSrcRect.bottom = picSrcRect.top + cellHeight;
  167.         if (picSrcRect.bottom > picMap.bounds.bottom) 
  168.             picSrcRect.bottom = picMap.bounds.bottom;
  169.         picDstRect = picSrcRect;
  170.         picDstRect.top = lRect->top;
  171.         picDstRect.bottom = picDstRect.top + picSrcRect.bottom - picSrcRect.top;
  172.         CopyBits(&picMap, &(**lHandle).port->portBits, &picSrcRect, &picDstRect, 
  173.             srcCopy, nil);
  174.         
  175.     } else {
  176.     
  177.         /* Draw a text line. */
  178.     
  179.         if (!escStyle) styleCode = normal;
  180.         if (!escJust) justCode = docLeft;
  181.         TextFace(styleCode);
  182.         nchar = *theLine - (q - theLine - 1);
  183.         if (nchar && *(q+nchar-1) == docEop) nchar--;
  184.         baseLine = lRect->bottom - 2;
  185.         switch (justCode) {
  186.             case docLeft:
  187.                 MoveTo(lRect->left + 4, baseLine);
  188.                 break;
  189.             case docCenter:
  190.                 MoveTo((lRect->left + lRect->right - TextWidth((Ptr)q, 0, nchar)) >> 1,
  191.                     baseLine);
  192.                 break;
  193.             case docRight:
  194.                 MoveTo(lRect->right - 4 - TextWidth((Ptr)q, 0, nchar), baseLine);
  195.                 break;
  196.         };
  197.         DrawText((Ptr)q, 0, nchar);
  198.         TextFace(normal);
  199.     };
  200.     
  201.     HUnlock(theStrings);
  202. }
  203.